﻿using System;
using System.Xml.Linq;
using static bank.CreditAccount;
namespace bank
{
    public interface IAccountOperations
    {
        bool Withdraw(int amount);
        bool Transfer(Account recipient, int amount);
    }

    public class Bank
    {
        public string Name { get;}
        public string Type { get;}
        int _accountNumber;
        public int accountNumber {
            get { return _accountNumber; }
            set { _accountNumber = value > 0 ? value : 0; } 
        }
        private Account[] accounts;
        private int accountId;
        public int getAccountId=>accountId;
        //如果你想为多个属性赋值，必须在构造函数的主体中进行，而不是通过初始化列表。
        //初始化列表只能用于调用基类构造函数或委托给当前类的另一个构造函数。
        public Bank(string name, string type, int number)
        {
            Name = name;                    // 初始化只读属性
            Type = type;
            accountNumber = number;         // 账户数目赋值
            accountId = 0;
            accounts = new Account[accountNumber];  // 初始化账户数组
        }
        public Bank(string name, string type) : this(name, type, 100){}
        public Account FindAccountByUsername(string username)
        {
            // 查找账户
            foreach (var account in accounts)
            {
                if (account != null && account.Username == username)
                {
                    return account;
                }
            }
            return null;
        }
        // 添加账户
        public void AddAccount(Account account)
        {
            if (accountId < accounts.Length)
            {
                accounts[accountId++] = account;
            }
        }
    }
    public class Account : IAccountOperations
    {
        public string Username {  get; set; }
        public string Bankname { get; set; }
        private int id;
        private int money;
        public int Balance=>money;//表达式语法，只读属性
        public Account(string username,string bankname, int initialMoney)
        {
            Username=username;
            Bankname=bankname;
            money = initialMoney >= 0 ? initialMoney : 0; // 确保初始金额为正数
            Console.WriteLine($"初始化账号：Username={Username}, Bank={Bankname}, Initial Balance={money}");
        }
        public bool Transfer(Account recipient, int amount)
        {
            if (amount <= 0 || amount > money)
            {
                return false; // 金额无效或余额不足
            }

            money -= amount;                // 扣除转出金额
            recipient.ReceiveMoney(amount); // 接收方增加金额
            return true;
        }
        public virtual bool Withdraw(int amount) // 提款方法
        {
            if (amount <= 0 || amount > money)
            {
                return false; // 金额无效或余额不足
            }

            money -= amount;
            return true;
        }

        private void ReceiveMoney(int amount)
        {
            money += amount; // 接收金额
        }
    }
    public class ATM
    {
        private Bank bank;

        public ATM(Bank bank)
        {
            this.bank = bank;
        }
        // 定义事件，用于大额取款通知
        public event EventHandler<BigMoneyArgs> BigMoneyFetched;
        public bool Withdraw(string username, int amount)
        {
            var account = bank.FindAccountByUsername(username);

            if (account == null)
            {
                return false; // 账户未找到
            }
            // 模拟坏钞的概率
            Random random = new Random();
            var test = random.NextDouble();
            Console.WriteLine($"概率为：{test}");
            if (test < 0.3) // 30% 的概率
            {
                Console.WriteLine($"概率小于0.3，发生纸张损坏");
                throw new BadCashException("Detected damaged cash, withdrawal aborted."); // 抛出自定义异常
            }

            if (account.Withdraw(amount))
            {
                // 如果取款金额大于10000元，触发事件
                if (amount > 10000)
                {
                    OnBigMoneyFetched(new BigMoneyArgs(account, amount));
                }
                return true;
            }
            return false;
        }
        // 激活事件方法
        protected virtual void OnBigMoneyFetched(BigMoneyArgs e)
        {
            BigMoneyFetched?.Invoke(this, e); // 如果事件有订阅者，则触发
        }

        public bool TransferMoney(string fromUsername, string toUsername, int amount)
        {
            var fromAccount = bank.FindAccountByUsername(fromUsername);
            var toAccount = bank.FindAccountByUsername(toUsername);

            if (fromAccount == null || toAccount == null)
            {
                return false; // 账户未找到
            }

            return fromAccount.Transfer(toAccount, amount); // 转账操作
        }
    }
    // 信用账户类，继承自 Account
    public class CreditAccount : Account
    {
        public int CreditLimit { get; private set; } // 信用额度

        public CreditAccount(string username, string bankname, int initialMoney, int creditLimit)
            : base(username, bankname, initialMoney)
        {
            CreditLimit = creditLimit;
            Console.WriteLine($"信用账号，额度为：{creditLimit}");
        }

        public override bool Withdraw(int amount)
        {
            // 覆盖提款方法，允许透支至信用额度
            if (amount <= 0 || amount > (Balance + CreditLimit))
            {
                return false; // 金额无效或超过信用额度
            }

            CreditLimit -= (amount - Balance > 0 ? amount - Balance : 0); // 减少信用额度
            return base.Withdraw(amount); // 执行基础提款操作
        }
        //事件
        public class BigMoneyArgs : EventArgs
        {
            public Account Account { get; }
            public int Amount { get; }

            public BigMoneyArgs(Account account, int amount)
            {
                Account = account;
                Amount = amount;
            }
        }
        // 定义自定义异常类 BadCashException
        public class BadCashException : Exception
        {
            public BadCashException(string message) : base(message) { }
        }
        class Program
        {
            static void Main(string[] args)
            {
                // 创建银行和账户
                Bank bank = new Bank("MyBank", "Retail");
                Account account1 = new Account("user1", "MyBank", 20000);
                CreditAccount account2 = new CreditAccount("user2", "MyBank", 5000, 10000);
                bank.AddAccount(account1);
                bank.AddAccount(account2);

                // 创建 ATM 并注册事件处理程序
                ATM atm = new ATM(bank);
                atm.BigMoneyFetched += (sender, e) =>
                {
                    Console.WriteLine($"警告: 银行{e.Account.Bankname}的ATM大额现金取出，用户名：{e.Account.Username}, 账户: {e.Amount}");
                };

                // 测试取款操作并捕获异常
                try
                {
                    Console.WriteLine("用户1试图取出15000...");
                    atm.Withdraw("user1", 15000);
                    Console.WriteLine("成功");
                }
                catch (BadCashException ex)
                {
                    Console.WriteLine($"Error: {ex.Message}");
                }

                // 测试信用账户取款
                try
                {
                    Console.WriteLine("信用卡用户2试图取出12000...");
                    atm.Withdraw("user2", 12000);
                    Console.WriteLine("成功");
                }
                catch (BadCashException ex)
                {
                    Console.WriteLine($"Error: {ex.Message}");
                }
            }
        }


    }
}